/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pl.butler.cezary.syncTool.storage;

import pl.butler.cezary.syncTool.storage.metadata.FileMetadata;
import pl.butler.cezary.syncTool.storage.metadata.FileVersionMetadata;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import pl.butler.cezary.syncTool.storage.metadata.IMetadataStorage;
import pl.butler.cezary.syncTool.storage.metadata.SerializedMetadataStorage;

/**
 *
 * @author czarek
 */
public class SimpleFileStorage extends Storage {

    private final File storagePath;
    private static final Logger log = Logger.getLogger(SimpleFileStorage.class.getSimpleName());

    public SimpleFileStorage(MagazynId magazyn) {
        super(magazyn);
        storagePath = new File(magazyn.getSciezka());      
    }

    @Override
    protected IMetadataStorage createMetadataStorage() {
        return new SerializedMetadataStorage(new File(storagePath, METADATA_FNAME));
    }
    private static final int HEX_LIMIT = 0x100000;

    protected File generateUid(final File source) {
        final FileVersionMetadata meta = getCurrentFileVersionMetadata(source); //czy można ufać że plik pozostanie niezmieniony?
        final String uid = String.format("%s-%05x%05x.bak", meta.getSumaKontrolna(),
                meta.getRozmiarPliku() % HEX_LIMIT, meta.getDataModyfikacji() % HEX_LIMIT);
        return new File(storagePath, uid);
    }
    private static final String METADATA_FNAME = "meta.dat";

    @Override    
    public void saveFile(File plik) {
        final File bakFile = generateUid(plik);
        if(bakFile.exists()){
            log.info("Plik jest już zapisany, pomijamy");
            //TODO CBU sprawdzenie czy napewno dane są aktualne
        }
        try {
            final FileOutputStream fileOutputStream = new FileOutputStream(bakFile);
            final FileInputStream fileInputStream = new FileInputStream(plik);
            final ReadableByteChannel inputChannel = Channels.newChannel(fileInputStream);
            final WritableByteChannel outputChannel = Channels.newChannel(fileOutputStream);
            try {
                ChannelUtils.fastChannelCopy(inputChannel, outputChannel);
            } finally {
                inputChannel.close();
                fileInputStream.close();
                outputChannel.close();
                fileOutputStream.close();
            }
        } catch (Exception e) {
            log.log(Level.SEVERE, String.format("Błąd podczas próby zapisania kopii pliku '%s'", plik.getPath()), e);
        }
    }

    @Override
    public void restoreFile(File plik) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

}
